﻿using Projet_IMA.Object3D;
using Projet_IMA.Light;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Projet_IMA.Environnement;
using Projet_IMA.Base;
using Projet_IMA.Unsafe;
using Projet_IMA.Habillage.Material;

namespace Projet_IMA
{
    public class Scene3D
    {
        private List<Object3DBase> Objects;
        private List<LightBase> Lights;
        private List<CachePoint> CachesObject;
        private List<MaterialBase> Materials;
        private SceneGrille Grille;
        private SceneRepere Repere;
        private bool modified;

        public Scene3D()
        {
            this.Objects = new List<Object3DBase>();
            this.Lights = new List<LightBase>();
            this.CachesObject = new List<CachePoint>();
            this.Materials = new List<MaterialBase>();
            this.Grille = new SceneGrille(1920, 1080, 400);
            this.Repere = new SceneRepere(this, 400);
            this._CameraDirection = new V3();
        }

        public List<LightBase> AllLights
        {
            get { return this.Lights; }
        }

        public V3 _CameraDirection;
        public V3 CameraDirection
        {
            get { return _CameraDirection; }
            set { _CameraDirection = value; _CameraDirection.Normalize(); }
        }

        public void AddObject(Object3DBase newObject)
        {
            if (!Objects.Contains(newObject))
            {
                Objects.Add(newObject);
                newObject.setScene(this);
                modified = true;
            }
        }

        public void AddLight(LightBase newLights)
        {
            if (!Lights.Contains(newLights))
            {
                Lights.Add(newLights);
                modified = true;
            }
        }

        public void AddMaterial(MaterialBase newMaterial)
        {
            if (!Materials.Contains(newMaterial))
            {
                Materials.Add(newMaterial);
                newMaterial.setScene(this);
                modified = true;
            }
        }

        public List<CachePoint> GetCacheObject()
        {
            if (this.modified)
            {
                this.MakeCacheObject();
                this.modified = false;
            }

            return CachesObject;
        }

        private void MakeCacheObject()
        {
            this.CachesObject.Clear();

            foreach (Object3DBase object3D in this.Objects)
                this.CachesObject.Add(object3D.GetCache());
        }

        public List<CachePoint> GetCacheGrille(EProjectionType type)
        {
            return this.Grille.GetCacheGrille(type);
        }

        public List<CachePoint> GetCacheRepere()
        {
            return this.Repere.GetCacheRepere();
        }

        public void IncreasesRepere()
        {
            this.Repere.Increases();
        }

        public void DecreasesRepere()
        {
            this.Repere.Decreases();
        }
    }
}
